

#include "APP_Main.h"
#include "Tool.h"
#include <math.h>


_Pt1000_State Pt1000_State;


//卡马克快速求平方根的倒数(替换标准库sqrt函数): 比标准库函数快4倍
float InvSqrt(float number)
{
    long i;
    float x2, y;

    x2 = number * 0.5;
    y  = number;
    i  = *(long *)&y; //evil floating point bit level hacking
    i  = 0x5f3759df - (i >> 1); // 计算第一个近似根 // what the fuck?
    y  = *(float *)&i;
    y  = y * (1.5 - (x2 * y * y)); //牛顿迭代法 // 1st iteration 
    y  = y * (1.5 - (x2 * y * y)); //2nd iteration, this can be removed

    return y;
}

//输入10进制数,返回个位/十位/百位的数字
uint32_t GetNums(uint32_t dat,_Num_unit bit)
{
    uint32_t temp;

    temp = (dat / (bit * 1)) % 10;
    return temp;
}


//根据分压电路转换成电阻
//输入 12位AD, 输出对应的 电阻值
double AD_Convert_R(uint32_t ad)
{
    double temp;

    temp = ad;
    if(temp <= 500)
    {
        temp = 7192; //AD <= 500时,认为电阻有 7192 Ω
    }
    else if(temp >= 4096)
    {
        temp = 0; //最小电阻 0 Ω
    }
    else
    { //根据分压电路,得出AD转电阻的公式
        temp = (4096.0 / temp - 1.0) * 1000.0; //以VDD为AD参考源,根据分压电路推导出 12位AD值转电阻的公式:  R = ((4096/AD) - 1) * 1000;  //1000是接地电阻1k
    } 

    return temp;
}

//将电压转成电阻
//输入的 VDD 
//V_Div 
float V_Convert_R(float Vdd,float V_Div)
{
    float R_Div = 1000.0;
    float R_Up;

    if(V_Div > (Vdd - 1000)) R_Up = 0;
    else if(V_Div < 100) R_Up = 10000; 
    else
    {
        R_Up = (R_Div * (Vdd - V_Div)) / V_Div; //上拉电阻 = (分压电阻 * (VDD - 分压)) / 分压 
        R_Up *= 0.9807; //补偿; Pt1000测量误差13~20Ω
    } 
    
    return R_Up;
}

//将摄氏度转华氏度
double CTemp_Convert_FTemp(double F_temp)
{
    F_temp *= 1.8;
    F_temp += 32;

    return F_temp;
}

//Pt1000电阻转C温度值
//Pt1000铂电阻的一元二次解温度公式
//输入电阻值, 例如 1000.000
//返回 C温度(有符号值),有效位小数点后2位
double Quadratic(float R_x)
{
    double a;
    double b;
    double c;
    double x = 0.0;

    if(R_x <= 803)
    { //判断Pt1000电阻 <= 100, 就认为铂电阻短路
        x = -222.935332;
        Pt1000_State = Pt1000_Short;
    }
    else if (R_x >= 3120)
    { //判断PT1000 开路
        x = 1256.896275;
        Pt1000_State = Pt1000_Open;
    }
    else
    {
        a = 1000.000;
        a *= -0.0000005775;
        b = 1000.000;
        b *= 0.0039083;
        c = 1000.000 - R_x;
        
        x = b * b - (4.0 * a * c);
        
		if(InvSqrt(x) != 0) x = (-b + 1.0/InvSqrt(x)) / (2.0 * a);
        Pt1000_State = Pt1000_Normal;
    }

    return x;
}
double Test_C;
//输入: Pt1000电阻, 输出: F温度值
double Quadratic_F(double R_x)
{
    double temp;
    
    temp = Quadratic(R_x);
    Test_C = temp;
    temp = CTemp_Convert_FTemp(temp);

    return temp;
}
